<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>贪吃蛇</title>
    <style>
        .map {
            position: relative;
            width: 800px;
            height: 600px;
            border: 1px solid #c0c0c0;
        }
    </style>
</head>
<body>
    <div class="map"></div>
    <script>
        // 有三个对象：食物 小蛇 游戏
        // 1.先把地图先做出来
        // 2.把食物做出来
        // 3.把小蛇做出来
        var map = document.querySelector('.map');
        (function () {
            // 存储食物
            var elements = [];
            function Food(width, height, color) {
                // 坐标
                this.x = 0;
                this.y = 0;
                // 样式
                this.width = width || 20;
                this.height = height || 20;
                this.color = color || 'orange';
            }
            // 初始化食物,传入地图用于获取宽高和插入食物
            Food.prototype.init = function (map) {
                // 删除食物
                this.remove();
                // 创建食物
                var cib = document.createElement('div');
                // 设置属性
                cib.style.position = 'absolute';
                cib.style.width = this.width + 'px';
                cib.style.height = this.height + 'px';
                cib.style.backgroundColor = this.color;
                // 渲染位置
                // 因为食物不能超出地图区域，所以值肯定是不能负值得，所以绝对值
                this.x = Math.abs(Math.floor(Math.random() * (map.offsetWidth / this.width) * this.width) - 20);
                this.y = Math.abs(Math.floor(Math.random() * (map.offsetHeight / this.height) * this.height) - 20);
                cib.style.left = this.x + 'px';
                cib.style.top = this.y + 'px';
                // 插入对象
                map.appendChild(cib);
                // 将食物存储进数组
                elements.push(cib);
            }
            Food.prototype.remove = function () {
                // 删除食物
                for(var i = 0; i < elements.length; i++) {
                    // 食物.父级.移除节点.食物：删除元素下的div(食物)
                    // 删除页面上的
                    elements[i].parentNode.removeChild(elements[i]);
                    // 删除数组上的
                    elements.splice(i,1);
                }
            }
            // 暴露对象给window对象,使得自调用函数外可以调用
            window.Food = new Food();
        }())
        // 调用食物初始化方法
        // Food.init(map);
        // 创建小蛇
        // (function () {
            // 存放小蛇的每个身体部分
            var elements = [];
            // 宽度和高度指的是身体每个小方块的，direction指的是方向
            function Snake(width,height,direction) {
                // 小蛇每个部分的宽
                this.width = width || 20;
                this.height = height || 20;
                // 小蛇的身体
                this.body =[
                    // x和y轴的距离按照小方块的宽度来算
                    {x: 3, y: 2, color: 'red'},//头
                    {x: 2, y: 2, color: 'orange'},//身体
                    {x: 1, y: 2, color: 'orange'},//身体
                ];
                this.direction = direction || 'left';
            };
            // 添加小蛇初始化方法，在原型上添加
            Snake.prototype.init = function (map) {
                // 删除之前的小蛇
                this.remove();
                // 创建小蛇--根据body数组,整个小蛇是由多个小方块组成的
                for(var i = 0; i < this.body.length; i++) {
                    // body数组中的每个对象就是一个元素
                    var obj = this.body[i];
                    // 创建方块
                    var div = document.createElement('div');
                    // 设置方块样式
                    div.style.position = 'absolute';
                    div.style.width = this.width + 'px';
                    div.style.height = this.height + 'px';
                    // 位置生成
                    // 之前我们提过，x和y就是按照小方块来算的，所以这里的x距离就是3 * 20px = 60px;
                    div.style.left = obj.x * this.width + 'px';
                    div.style.top = obj.y * this.height + 'px';
                    // 赋值小方块颜色--obj就是之前缓存的当前第一个对象 如第一次循环就是：body[i]  相当于 body[0]个对象
                    div.style.backgroundColor = obj.color;
                    // 方向？？？ 不设置先
                    // 把方块加入到map地图中
                    map.appendChild(div);
                    // 将方块加入存储小蛇的数组中，为了下次生成小蛇的时候，清空上次创建的小蛇
                    elements.push(div);
                }
            }
            Snake.prototype.move = function (map, food) {
                for(var i = this.body.length - 1; i > 0; i--) {
                    this.body[i].x = this.body[i - 1].x;
                    this.body[i].y = this.body[i - 1].y;
                }
                switch(this.direction) {
                    case 'top':
                    this.body[0].y -= 1;
                    break;
                    case 'right':
                    this.body[0].x += 1;
                    break;
                    case 'bottom':
                    this.body[0].y += 1;
                    case 'left':
                    this.body[0].x -= 1;
                    break;
                }
                var HeadX = this.body[0].x * this.width;
                var HeadY = this.body[0].y * this.height;
                // 小蛇的头的位置和小方块的位置一样的话，就移除食物对象并且自身+1
                if(HeadX == food.x && HeadY == food.y) {
                    // 找到蛇的最后一个小方块，复制一份，加给自身
                    var last = this.body[this.body.length - 1];
                    // 追加到尾部
                    this.body.push({
                        x: last.x,
                        y: last.y,
                        color: last.color
                    })
                    // 重新初始化小方块
                    food.init(map);
                }
            }
            Snake.prototype.remove = function () {
                for(var i = 0; i < elements.length; i++) {
                    // 缓存当前对象
                    var ele = elements[i];
                    // 当前对象父级下的当前元素删除
                    ele.parentNode.removeChild(ele);
                    // 删除当前索引下的1
                    elements.spclie(i,1);
                }
            }
            // 暴露对象给window ，使函数外可以调用
            window.Snake = new Snake();
        // }())
        Snake.init(map);
    </script>
</body>
</html>